package com.fly.snailrun.utils;

import cn.hutool.core.util.IdUtil;
import com.fly.snailrun.base.exception.BusinessErrorCodeEnum;
import com.fly.snailrun.base.exception.BusinessException;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import org.apache.commons.lang3.StringUtils;
import org.bytedeco.javacpp.Loader;

import java.io.File;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;

/**
 * @author：gaoxu
 * @date：Created in 2024/8/12 10:00
 */
public class CutOutTool {
    /**
     * 视频裁剪
     *
     * @param videoPath 视频地址
     * @param outputDir 临时目录
     * @param startX    裁剪起始x坐标
     * @param startY    裁剪起始y坐标
     * @param weight    裁剪宽度
     * @param height    裁剪高度
     * @throws Exception 异常
     */
    public static String cutOutVideo(String videoPath, String outputDir, Integer startX,
                                     Integer startY, Integer weight, Integer height) {
        List<String> paths = Splitter.on(".").splitToList(videoPath);
        String ext = paths.get(paths.size() - 1);
        if (!Arrays.asList("mp4", "avi", "flv").contains(ext)) {
            throw new BusinessException(BusinessErrorCodeEnum.Exception);
        }
        String resultPath = Joiner.on(File.separator).join(Arrays.asList(outputDir, IdUtil.simpleUUID() + "." + ext));
        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        ProcessBuilder builder =
                new ProcessBuilder(
                        ffmpeg, "-i", videoPath, "-vf", MessageFormat.format("crop={0}:{1}:{2}:{3}",
                        String.valueOf(weight),
                        String.valueOf(height),
                        String.valueOf(startX),
                        String.valueOf(startY)),
                        "-b",
                        "2000k",
                        "-y",
                        "-threads",
                        "5",
                        "-preset",
                        "ultrafast",
                        "-strict",
                        "-2",
                        resultPath);
        try {
            builder.inheritIO().start().waitFor();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return resultPath;
    }

    /**
     * 视频裁剪按照固定时间切割
     *
     * @param videoPath 视频地址
     * @param outputDir 临时目录
     * @param cutTime   视频分割时间,默认5秒
     * @throws Exception 异常
     */
    public static void cutOutVideo(String videoPath, String outputDir, String cutTime) {
        List<String> paths = Splitter.on(".").splitToList(videoPath);
        String ext = paths.get(paths.size() - 1);
        if (!Arrays.asList("mp4", "avi", "flv").contains(ext)) {
            throw new BusinessException(BusinessErrorCodeEnum.Exception);
        }
        // 设置默认值按照5秒进行切割
        if (StringUtils.isEmpty(cutTime)) {
            cutTime = "5";
        }
        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        ProcessBuilder builder = new ProcessBuilder(
                ffmpeg, "-i", videoPath, "-c", "copy", "-map", "0", "-segment_time", cutTime,
                "-f", "segment", outputDir + "frame_%05d.mp4"
        );
        try {
            builder.inheritIO().start().waitFor();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 视频关键帧图片抽取
     *
     * @param videoPath 视频地址
     * @param outputDir 临时目录
     * @throws Exception 异常
     */
    public static void videoPhotoExtract(String videoPath, String outputDir) {
        List<String> paths = Splitter.on(".").splitToList(videoPath);
        String ext = paths.get(paths.size() - 1);
        if (!Arrays.asList("mp4", "avi", "flv").contains(ext)) {
            throw new BusinessException(BusinessErrorCodeEnum.Exception);
        }
        String ffmpeg = Loader.load(org.bytedeco.ffmpeg.ffmpeg.class);
        ProcessBuilder builder =
                new ProcessBuilder(
                        ffmpeg, "-i", videoPath, "-vf", "select='gt(scene,0.3)',showinfo",
                        "-vsync", "vfr", outputDir + "frame_%04d.png");
        try {
            builder.inheritIO().start().waitFor();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
